import com.db4o.Db4oEmbedded;
import com.db4o.ObjectContainer;
import com.db4o.ObjectSet;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import javax.swing.Action;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.WindowConstants;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author lupo
 */
public class LazadaWindow extends javax.swing.JFrame {

    MainMenu mainMenu;
    short lazoNo;
    MyTableModel lazoTableModel;
    
    /**
     * Creates new form LazadaWindow
     */
    @SuppressWarnings("OverridableMethodCallInConstructor")
    public LazadaWindow(MainMenu mainMenu, short lazoNo) {
        this.mainMenu = mainMenu;
        this.lazoNo = lazoNo;
        
        
        lazoTableModel = new MyTableModel();
        lazoTableModel.addColumn("Cabecero");
        lazoTableModel.addColumn("#");
        lazoTableModel.addColumn("Patero");
        lazoTableModel.addColumn("#");
        lazoTableModel.addColumn("Vuelta 1");
        lazoTableModel.addColumn("Vuelta 2");
        lazoTableModel.addColumn("Short Go");
        lazoTableModel.addColumn("+/-");
        
        initComponents();
        
        //Set table headers font and sizes
        lazoTable.getTableHeader().setFont(new java.awt.Font("Tahoma", 0, 18));
        lazoTable.getTableHeader().getColumnModel().getColumn(0).setPreferredWidth(235);
        lazoTable.getTableHeader().getColumnModel().getColumn(1).setPreferredWidth(30);
        lazoTable.getTableHeader().getColumnModel().getColumn(2).setPreferredWidth(235);
        lazoTable.getTableHeader().getColumnModel().getColumn(3).setPreferredWidth(30);
        lazoTable.getTableHeader().getColumnModel().getColumn(4).setPreferredWidth(95);
        lazoTable.getTableHeader().getColumnModel().getColumn(5).setPreferredWidth(95);
        lazoTable.getTableHeader().getColumnModel().getColumn(6).setPreferredWidth(95);
        lazoTable.getTableHeader().getColumnModel().getColumn(7).setPreferredWidth(55);
        
        //Set table renderer for centering information
        DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
        renderer.setHorizontalAlignment(JLabel.CENTER);
        for (int i=0; i<lazoTable.getColumnCount();i++){
            lazoTable.setDefaultRenderer(lazoTable.getColumnClass(i),renderer);
        }
        
        /*
        Object[] contestant = {
            "Cabecero",
            "#",
            "Patero",
            "#",
            "Vuelta 1",
            "Vuelta 2",
            "Short Go",
            "+/-"
        };
        lazoTableModel.addRow(contestant);
        */
        setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
        //Fill table with pairs information
        initializeLazo();
        
        //Save max lazo done
        
        List<Tournament> tournaments = mainMenu.db.query(Tournament.class);
        Tournament tournament = tournaments.get(0);
        if (lazoNo >= tournament.currentLazo && lazoNo<tournament.lazos){
            tournament.setCurrentLazo((short)(lazoNo+1));
            mainMenu.db.store(tournament);
            mainMenu.currentLazo = (short)(lazoNo+1);
        }
        
        //Make sure changes are saved
        mainMenu.db.commit();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        lazoTable = new javax.swing.JTable();
        copyButton = new javax.swing.JButton();
        backButton = new javax.swing.JButton();
        fillButton = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setResizable(false);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosed(java.awt.event.WindowEvent evt) {
                formWindowClosed(evt);
            }
        });

        lazoTable.setFont(new java.awt.Font("Tahoma", 0, 18)); // NOI18N
        lazoTable.setModel(lazoTableModel);
        lazoTable.setRowHeight(25);
        lazoTable.getTableHeader().setReorderingAllowed(false);
        jScrollPane1.setViewportView(lazoTable);

        copyButton.setFont(new java.awt.Font("Tahoma", 0, 18)); // NOI18N
        copyButton.setText("Copiar");
        copyButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                copyButtonActionPerformed(evt);
            }
        });

        backButton.setFont(new java.awt.Font("Tahoma", 0, 18)); // NOI18N
        backButton.setText("Regresar");
        backButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                backButtonActionPerformed(evt);
            }
        });

        fillButton.setFont(new java.awt.Font("Tahoma", 0, 18)); // NOI18N
        fillButton.setText("Llenar");
        fillButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                fillButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane1)
                .addContainerGap())
            .addGroup(layout.createSequentialGroup()
                .addGap(79, 79, 79)
                .addComponent(backButton, javax.swing.GroupLayout.PREFERRED_SIZE, 123, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(182, 182, 182)
                .addComponent(copyButton, javax.swing.GroupLayout.PREFERRED_SIZE, 109, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 190, Short.MAX_VALUE)
                .addComponent(fillButton, javax.swing.GroupLayout.PREFERRED_SIZE, 123, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(64, 64, 64))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addGap(23, 23, 23)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(copyButton, javax.swing.GroupLayout.PREFERRED_SIZE, 42, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(backButton, javax.swing.GroupLayout.PREFERRED_SIZE, 42, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(fillButton, javax.swing.GroupLayout.PREFERRED_SIZE, 42, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 26, Short.MAX_VALUE)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 448, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
        setBounds((screenSize.width-886)/2, (screenSize.height-589)/2, 886, 589);
    }// </editor-fold>//GEN-END:initComponents

    private void formWindowClosed(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosed
        //dispose();
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                mainMenu.setVisible(true);
            }
        });
    }//GEN-LAST:event_formWindowClosed

    private void copyButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_copyButtonActionPerformed
        //This code copies table contents to clipboard
        lazoTable.selectAll();
        Action copy = lazoTable.getActionMap().get("copy");
        ActionEvent ae = new ActionEvent(lazoTable, ActionEvent.ACTION_PERFORMED, "");
        copy.actionPerformed(ae);
    }//GEN-LAST:event_copyButtonActionPerformed

    private void backButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_backButtonActionPerformed
        dispose();
        mainMenu.setVisible(true);
        mainMenu.lazadaSpinner.setSelectedIndex(mainMenu.currentLazo-1);
    }//GEN-LAST:event_backButtonActionPerformed

    private void fillButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fillButtonActionPerformed
        Component frame = null;
        JOptionPane.showMessageDialog(frame,
            "Para adquirir esta funcionalidad por favor comúniquese con Lienzo","Lazada Sierra Grande - Lienzo",
            JOptionPane.PLAIN_MESSAGE);
    }//GEN-LAST:event_fillButtonActionPerformed

    /**
     * @param args the command line arguments
     */
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton backButton;
    private javax.swing.JButton copyButton;
    private javax.swing.JButton fillButton;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTable lazoTable;
    // End of variables declaration//GEN-END:variables

    public void initializeLazo(){
        //Check if pairs for this lazada has been filled or not
        List<Pair> pairs = mainMenu.db.queryByExample(new Pair(0,0,lazoNo));
        if (pairs.isEmpty()){
            //Calculate pairs
            calculatePairs();
        }
        
        //Fill table
        fillTable();
    }
    
    /*
     * This method runs only in case this lazo's pairs are not yet
     * calcullated. This is checked in the initializeLazo() method
     */
    public void calculatePairs(){
        ArrayList<Cabecero> cabeceros = new ArrayList(mainMenu.db.query(Cabecero.class));
        ArrayList<Patero> pateros = new ArrayList(mainMenu.db.query(Patero.class));
        
        int noPateros = pateros.size();
        
        Random rand = new Random(System.currentTimeMillis());
        
        //ques
        ArrayList<Cabecero> lastCabeceros = new ArrayList<>();
        ArrayList<Patero> lastPateros = new ArrayList<>();
        
        //Register normal pairs
        while (!cabeceros.isEmpty() && !pateros.isEmpty()){
            Cabecero cabecero = cabeceros.get(rand.nextInt(999999999)
                    % cabeceros.size());
            //Create temporal list
            List<Patero> paterosTemp = (ArrayList) pateros.clone();
            //Get a random patero
            Patero patero = paterosTemp.get(rand.nextInt(999999999)
                    % paterosTemp.size());
            short mod;
            short c=0;
            boolean removePrevious = true;
            //Get a random patero until a valid pair ia calcullated
            ObjectSet result = mainMenu.db.queryByExample(new Pair(
                    cabecero.id, patero.id, (short)0));
            while (!result.isEmpty() && paterosTemp.size()>1){
                c++;
                if (removePrevious){
                    paterosTemp.remove(patero);
                }
                removePrevious = true;
                patero = paterosTemp.get(rand.nextInt(999999999)
                    % paterosTemp.size());
                result = mainMenu.db.queryByExample(new Pair(
                    cabecero.id, patero.id, (short)0));
                mod = (short) (cabecero.range + patero.range - mainMenu.capada);
                //System.out.println("Mod: "+mod);
                if (result.isEmpty() && c<=noPateros*2 && mod>0){
                    removePrevious = false;
                    result = mainMenu.db.queryByExample(new Pair(0,0,(short)0));
                    //System.out.println("Result a proposito: "+result.size());
                }
            }
            
            mainMenu.db.store(new Pair(cabecero.id, patero.id, lazoNo));
            insertCabeceroQue(lastCabeceros, cabecero);
            insertPateroQue(lastPateros, patero);
            
            cabeceros.remove(cabecero);
            pateros.remove(patero);
        }
        
        //Calcullate help pairs for cabeceros
        if (!cabeceros.isEmpty()){
            //Get all pateros but the last 6 used
            pateros = new ArrayList(mainMenu.db.query(Patero.class));
            System.out.println("tamaño: "+pateros.size());
            for (int i=0; i<lastPateros.size(); i++)
                pateros.remove(lastPateros.get(i));
            System.out.println("tamaño: "+pateros.size());
            while (!cabeceros.isEmpty()){
                Cabecero cabecero = cabeceros.get(rand.nextInt(999999999)
                    % cabeceros.size());
                Patero patero;
                if (!pateros.isEmpty()){
                    patero = pateros.get(rand.nextInt(999999999) % pateros.size());
                    pateros.add(lastPateros.get(0));
                    insertPateroQue(lastPateros, patero);
                }
                else patero = new Patero(-1,"Sin Pareja",0);
                mainMenu.db.store(new Pair(cabecero.id, Math.abs(patero.id)*-1,lazoNo));
                cabeceros.remove(cabecero);
                pateros.remove(patero);
            }
            
            pateros.clear();
        }
        //Calcullate help pairs for pateros
        else if (!pateros.isEmpty()){
            //Get all the cabeceros but the last 6 used
            cabeceros = new ArrayList(mainMenu.db.query(Cabecero.class));
            for (int i=0; i<lastCabeceros.size(); i++)
                cabeceros.remove(lastCabeceros.get(i));
            
            while(!pateros.isEmpty()){
                Patero patero = pateros.get(rand.nextInt(999999999)
                    % pateros.size());
                Cabecero cabecero;
                if (!cabeceros.isEmpty()){
                    cabecero = cabeceros.get(rand.nextInt(999999999) % cabeceros.size());
                    cabeceros.add(lastCabeceros.get(0));
                    insertCabeceroQue(lastCabeceros, cabecero);
                }
                else cabecero = new Cabecero(-1,"Sin Pareja",0);
                mainMenu.db.store(new Pair(Math.abs(cabecero.id)*-1, patero.id,lazoNo));
                pateros.remove(patero);
                cabeceros.remove(cabecero);
            }
        }
    }
    
    public void insertCabeceroQue(ArrayList<Cabecero> list, Cabecero cabecero){
        if (list.size()>=6)
            list.remove(0);
        list.add(cabecero);
    }
    
    public void insertPateroQue(ArrayList<Patero> list, Patero patero){
        if (list.size()>=6)
            list.remove(0);
        list.add(patero);
    }
    
    //Simply fills the table with the proper pairs information
    public void fillTable(){
        
        short capada = mainMenu.capada;
        
        ObjectSet pairsSet = mainMenu.db.queryByExample(new Pair(0,0,lazoNo));
        List<Pair> pairs = new ArrayList(pairsSet);
        
        for (int i=0; i<pairs.size(); i++){
            
            String cabeceroName = null;
            Cabecero cabecero;
            if (pairs.get(i).cabeceroId==-1)
                cabecero = new Cabecero(0,"Sin Pareja",0);
            else {
                ObjectSet result = mainMenu.db.queryByExample(new Cabecero(
                        Math.abs(pairs.get(i).cabeceroId),null,0));
                cabecero = (Cabecero) result.next();
                if (pairs.get(i).cabeceroId<0)
                    cabeceroName = "(A) "+cabecero.name;
                else
                    cabeceroName = cabecero.name;
            }
            
            String pateroName = null;
            Patero patero;
            if (pairs.get(i).pateroId==-1)
                patero = new Patero(0,"Sin Pareja",0);
            else {
                ObjectSet result = mainMenu.db.queryByExample(new Patero(
                        Math.abs(pairs.get(i).pateroId),null,0));
                patero = (Patero) result.next();
                if (pairs.get(i).pateroId<0)
                    pateroName = "(A) "+patero.name;
                else
                    pateroName = patero.name;
            }
            
            short mod = (short) (cabecero.range + patero.range - capada);
            
            String modStr = "0";
            if (mod>0) modStr = "+"+Short.toString(mod);
            else if (mod<0) modStr = Short.toString(mod);
            
            if (cabecero.range==0 || patero.range==0)
                modStr = "?";
            
            Object[] pair = {
                cabeceroName,
                cabecero.range,
                pateroName,
                patero.range,
                "",
                "",
                "",
                modStr,
            };
            lazoTableModel.addRow(pair);
        }
    }
    
    class MyTableModel extends DefaultTableModel {
        
        MyTableModel(){
            super();
        }
        
        @Override
        public boolean isCellEditable(int row, int cols){
            return false;
        }
    }
}